#include "../../Coroutine/TimerManager.hpp"
#include "../../base/BaseLog.hpp"
#include "../../Coroutine/Channel.hpp"
#include "../../base/TimeUnit.hpp"
#include <cstdint>
#include <functional>
#include <vector>

using DBServer::Base::Timer::Time;
Time test_clock;

using namespace DBServer::coroutine;

Channel chan1{}, chan2{}, chan3{};

#define TEST(X)                                                       \
    void cb_##X()                                                     \
    {                                                                 \
        test_clock.cur();                                             \
        debug("time %s begin cb %d", test_clock.format().c_str(), X); \
        char sinal = 't';                                             \
        chan##X < &sinal;                                             \
    }                                                                 \
    void cb_##X_##X()                                                 \
    {                                                                 \
        test_clock.cur();                                             \
        debug("time %s begin cb %d", test_clock.format().c_str(), 1); \
        char sinal = 't';                                             \
        chan##X < &sinal;                                             \
    }

TEST(1)
TEST(2)
TEST(3)

void test() {
    info("-----------------------timer manager test------------------------\n");
    TimerManager tm;
    auto timer1 = tm.add_timer(10000, cb_1);
    auto timer2 = tm.add_timer(10000, cb_2);
    auto timer3 = tm.add_timer(10000, cb_3);

    int counter = 0;
    while (counter != 3)
    {
        std::vector<std::function<void()>> cbs;
        tm.list_expire_cb(cbs);
        counter += cbs.size();
        for (int i = 0; i < cbs.size(); ++ i)
        {
            cbs[i]();
        }
    }

    char buf[1];
    chan1 > buf;
    chan2 > buf;
    chan3 > buf;

    info("reset timer");
    info("--------------------timer manager test pass---------------------\n");
}

int main(int argc, const char** argv) {
    test();
    return 0;
}